#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
测试记忆模式功能验证

本测试文件用于验证MCP2项目的记忆模式功能是否正常工作，
包括记忆创建、搜索、对话管理、知识上传等核心功能。
"""

import pytest
import asyncio
import sys
import os
from datetime import datetime
from pathlib import Path

# 添加项目根目录到Python路径
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))

try:
    from src.core.memory_manager import MemoryManager
    from src.core.conversation_manager import ConversationManager
    from src.core.knowledge_processor import KnowledgeProcessor
    from src.database.manager import DatabaseManager
    from src.config import load_config
except ImportError as e:
    print(f"导入模块失败: {e}")
    print("请确保项目依赖已正确安装")
    sys.exit(1)


class TestMemoryModeValidation:
    """记忆模式功能验证测试类"""
    
    @pytest.fixture(scope="class")
    async def setup_managers(self):
        """设置测试环境"""
        try:
            # 加载配置
            config = load_config()
            
            # 初始化数据库管理器
            db_manager = DatabaseManager(config)
            await db_manager.connect_all()
            
            # 初始化各个管理器
            memory_manager = MemoryManager(db_manager)
            conversation_manager = ConversationManager(db_manager)
            knowledge_processor = KnowledgeProcessor(db_manager)
            
            return {
                'db_manager': db_manager,
                'memory_manager': memory_manager,
                'conversation_manager': conversation_manager,
                'knowledge_processor': knowledge_processor,
                'config': config
            }
        except Exception as e:
            pytest.fail(f"设置测试环境失败: {e}")
    
    @pytest.mark.asyncio
    async def test_memory_creation(self, setup_managers):
        """测试记忆创建功能"""
        managers = await setup_managers
        memory_manager = managers['memory_manager']
        
        # 测试数据
        test_memory = {
            'user_id': 'test_user_memory_mode',
            'content': '测试记忆模式：这是一个长期开发项目的重要记忆',
            'memory_type': 'episodic',
            'importance': 0.8,
            'tags': ['测试', '记忆模式', '长期项目']
        }
        
        try:
            # 创建记忆
            memory_id = await memory_manager.create_memory(
                user_id=test_memory['user_id'],
                content=test_memory['content'],
                memory_type=test_memory['memory_type'],
                importance=test_memory['importance'],
                tags=test_memory['tags']
            )
            
            assert memory_id is not None, "记忆创建失败，返回None"
            assert isinstance(memory_id, str), "记忆ID应该是字符串类型"
            print(f"✓ 记忆创建成功，ID: {memory_id}")
            
        except Exception as e:
            pytest.fail(f"记忆创建测试失败: {e}")
    
    @pytest.mark.asyncio
    async def test_memory_search(self, setup_managers):
        """测试记忆搜索功能"""
        managers = await setup_managers
        memory_manager = managers['memory_manager']
        
        try:
            # 搜索记忆
            search_results = await memory_manager.search_memories(
                user_id='test_user_memory_mode',
                query='长期开发项目',
                memory_type='episodic',
                limit=5
            )
            
            assert isinstance(search_results, list), "搜索结果应该是列表类型"
            print(f"✓ 记忆搜索成功，找到 {len(search_results)} 条记忆")
            
            # 打印搜索结果
            for i, memory in enumerate(search_results):
                print(f"  记忆 {i+1}: {memory.get('content', 'N/A')[:50]}...")
                
        except Exception as e:
            pytest.fail(f"记忆搜索测试失败: {e}")
    
    @pytest.mark.asyncio
    async def test_conversation_creation(self, setup_managers):
        """测试对话创建功能"""
        managers = await setup_managers
        conversation_manager = managers['conversation_manager']
        
        try:
            # 创建对话
            conversation_data = await conversation_manager.create_conversation(
                user_id='test_user_memory_mode',
                title='记忆模式测试对话',
                metadata={
                    'type': 'memory_mode_test',
                    'project': 'MCP2',
                    'purpose': '验证记忆模式功能'
                }
            )
            
            assert conversation_data is not None, "对话创建失败"
            assert 'conversation_id' in conversation_data, "对话数据缺少conversation_id"
            
            conversation_id = conversation_data['conversation_id']
            print(f"✓ 对话创建成功，ID: {conversation_id}")
            
            return conversation_id
            
        except Exception as e:
            pytest.fail(f"对话创建测试失败: {e}")
    
    @pytest.mark.asyncio
    async def test_knowledge_upload(self, setup_managers):
        """测试知识上传功能"""
        managers = await setup_managers
        knowledge_processor = managers['knowledge_processor']
        
        # 测试文档内容
        test_document = """
        # MCP2记忆模式测试文档
        
        ## 项目概述
        MCP2是一个多层记忆系统项目，支持长期开发过程中的知识积累和上下文保持。
        
        ## 核心功能
        1. 记忆创建和管理
        2. 智能搜索和检索
        3. 对话历史管理
        4. 知识图谱构建
        5. 上下文感知处理
        
        ## 技术特性
        - 支持多种记忆类型：短期、长期、关联、语义
        - 向量化语义搜索
        - 图数据库关系管理
        - 分布式缓存系统
        
        ## 应用场景
        适用于需要长期知识积累的开发项目，如AI系统开发、复杂软件架构设计等。
        """
        
        try:
            # 上传知识文档
            result = await knowledge_processor.upload_document(
                title='MCP2记忆模式测试文档',
                content=test_document,
                user_id='test_user_memory_mode',
                metadata={
                    'type': 'test_document',
                    'category': 'technical_documentation',
                    'project': 'MCP2',
                    'tags': ['测试', '记忆模式', '技术文档']
                }
            )
            
            assert result is not None, "知识上传失败"
            assert result.get('success', False), "知识上传未成功"
            
            document_id = result.get('document_id')
            print(f"✓ 知识上传成功，文档ID: {document_id}")
            
        except Exception as e:
            pytest.fail(f"知识上传测试失败: {e}")
    
    @pytest.mark.asyncio
    async def test_knowledge_search(self, setup_managers):
        """测试知识搜索功能"""
        managers = await setup_managers
        knowledge_processor = managers['knowledge_processor']
        
        try:
            # 搜索知识
            search_results = await knowledge_processor.search_knowledge(
                query='多层记忆系统',
                user_id='test_user_memory_mode',
                limit=5
            )
            
            assert isinstance(search_results, list), "搜索结果应该是列表类型"
            print(f"✓ 知识搜索成功，找到 {len(search_results)} 个结果")
            
            # 打印搜索结果
            for i, result in enumerate(search_results):
                title = result.get('title', 'N/A')
                score = result.get('score', 0)
                print(f"  结果 {i+1}: {title} (相似度: {score:.3f})")
                
        except Exception as e:
            pytest.fail(f"知识搜索测试失败: {e}")
    
    @pytest.mark.asyncio
    async def test_conversation_search(self, setup_managers):
        """测试对话搜索功能"""
        managers = await setup_managers
        conversation_manager = managers['conversation_manager']
        
        try:
            # 搜索对话
            search_results = await conversation_manager.search_conversations(
                query='记忆模式',
                user_id='test_user_memory_mode',
                limit=5
            )
            
            assert isinstance(search_results, list), "搜索结果应该是列表类型"
            print(f"✓ 对话搜索成功，找到 {len(search_results)} 个对话")
            
            # 打印搜索结果
            for i, conversation in enumerate(search_results):
                title = conversation.get('title', 'N/A')
                created_at = conversation.get('created_at', 'N/A')
                print(f"  对话 {i+1}: {title} (创建时间: {created_at})")
                
        except Exception as e:
            pytest.fail(f"对话搜索测试失败: {e}")
    
    @pytest.mark.asyncio
    async def test_database_connections(self, setup_managers):
        """测试数据库连接状态"""
        managers = await setup_managers
        db_manager = managers['db_manager']
        
        try:
            # 检查各个数据库连接状态
            connections = {
                'MongoDB': await db_manager.mongodb_client.ping() if db_manager.mongodb_client else False,
                'Redis': await db_manager.redis_client.ping() if db_manager.redis_client else False,
                'Neo4j': await db_manager.neo4j_client.ping() if db_manager.neo4j_client else False,
                'ChromaDB': await db_manager.chromadb_client.ping() if db_manager.chromadb_client else False
            }
            
            print("\n数据库连接状态:")
            for db_name, status in connections.items():
                status_text = "✓ 连接正常" if status else "✗ 连接失败"
                print(f"  {db_name}: {status_text}")
            
            # 至少要有一个数据库连接正常
            assert any(connections.values()), "所有数据库连接都失败"
            
        except Exception as e:
            pytest.fail(f"数据库连接测试失败: {e}")
    
    @pytest.mark.asyncio
    async def test_memory_mode_config(self):
        """测试记忆模式配置文件"""
        try:
            # 检查记忆模式配置文件是否存在
            config_path = project_root / 'config' / 'memory_mode.yaml'
            assert config_path.exists(), f"记忆模式配置文件不存在: {config_path}"
            
            # 尝试加载配置
            import yaml
            with open(config_path, 'r', encoding='utf-8') as f:
                memory_config = yaml.safe_load(f)
            
            assert 'memory_mode' in memory_config, "配置文件缺少memory_mode节点"
            assert memory_config['memory_mode']['enabled'], "记忆模式未启用"
            
            print("✓ 记忆模式配置文件验证成功")
            print(f"  项目名称: {memory_config['memory_mode']['project']['name']}")
            print(f"  项目类型: {memory_config['memory_mode']['project']['type']}")
            print(f"  启动日期: {memory_config['memory_mode']['project']['start_date']}")
            
        except Exception as e:
            pytest.fail(f"记忆模式配置测试失败: {e}")
    
    @pytest.mark.asyncio
    async def test_cleanup(self, setup_managers):
        """清理测试数据"""
        managers = await setup_managers
        db_manager = managers['db_manager']
        
        try:
            # 关闭数据库连接
            await db_manager.close_all()
            print("✓ 测试清理完成")
            
        except Exception as e:
            print(f"清理过程中出现错误: {e}")


def run_memory_mode_tests():
    """运行记忆模式测试"""
    print("\n" + "="*60)
    print("MCP2 记忆模式功能验证测试")
    print("="*60)
    
    # 运行测试
    pytest_args = [
        __file__,
        '-v',
        '--tb=short',
        '--asyncio-mode=auto'
    ]
    
    exit_code = pytest.main(pytest_args)
    
    if exit_code == 0:
        print("\n✓ 所有记忆模式功能测试通过！")
        print("记忆模式已成功开启，可以开始长期开发工作。")
    else:
        print("\n✗ 部分测试失败，请检查系统配置和依赖。")
    
    return exit_code


if __name__ == '__main__':
    # 直接运行测试
    run_memory_mode_tests()